home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / networking / pgpuam / sources / pgpuamclientlogindialog.c < prev    next >
Encoding:
Text File  |  2000-06-23  |  16.4 KB  |  587 lines

  1. /*
  2.     File:            PGPUAMclientLoginDialog.c
  3.  
  4.     Description:    Handles the PGPlogin Username Dialog
  5.  
  6.     Written by:    Vinnie Moscaritolo
  7.  
  8.     Copyright:    © 1998 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.     You may incorporate this sample code into your applications without
  13.     restriction, though the sample code has been provided "AS IS" and the
  14.     responsibility for its operation is 100% yours.  However, what you are
  15.     not permitted to do is to redistribute the source as "DSC Sample Code"
  16.     after having made changes. If you're going to re-distribute the source,
  17.     we require that you make it clear in the source that the code was
  18.     descended from Apple Sample Code, but that you've made changes.
  19. */
  20.  
  21. //------------------------------------------------------------------------------------
  22. #pragma mark Includes
  23. //------------------------------------------------------------------------------------
  24.  
  25. #include <stdio.h>
  26. #include <string.h>
  27.  
  28. #include <Appearance.h>
  29. #include <Dialogs.h>
  30. #include <Controls.h>
  31. #include <DateTimeUtils.h>
  32. #include <PLStringFuncs.h>
  33.  
  34.  
  35. #include "PGPUAMclient.h"
  36. #include "PGPUAMclientLoginDialog.h"
  37.  
  38. #include "LaunchApplication.h"
  39.  
  40. #include "TMacException.h"
  41. #include "TASIPPGPkey.h"
  42. #include "TASIPKeyPane.h"
  43. #include "TAboutBoxPane.h"
  44. #include "TSetupPane.h"
  45. #include "TPGPUAMPrefs.h"
  46. #include "PassphraseCache.h"
  47.  
  48.  
  49. //------------------------------------------------------------------------------------
  50. #pragma mark Local Defines
  51. //------------------------------------------------------------------------------------
  52.  
  53. const OSType kPGPkeysCreator    = 'pgpK';
  54.  
  55. #define kLoginDialogID 130
  56.      
  57.  static enum {
  58.     kConnectID     = 1,
  59.     kCancelID ,            // 2  
  60.     kChangeKeyID,        // 37
  61.     kUserNameID,        // 3  
  62.     STXT4_Name,            // 4
  63.     kInfoID,            // 5
  64.      kIcon,                // 6
  65.     kDisclosureTri,        // 7
  66.     kHelpItem,            // 9
  67.     kLaunchPGPKeysButton,// 35
  68.     kKeyIcon,            // 10
  69.     kProgressArrowsID,    // 12
  70.     kDisclosureText,    // 13
  71.     kTabsID,            // 14
  72.     kSeperatorLine,        // 15
  73.     KLastLoginDialogItem
  74.      } ;
  75.  
  76. #define kDialogStringsID 128 
  77.  
  78. static enum {
  79.     kNoDetailsStrID      =1,
  80.     kShowDetailsStrID,
  81.     kHideDetailsStrID,
  82.     kServerKeyNotFound,
  83.     kServerKeyNotFoundErrorMsg1,
  84.     kServerKeyNotFoundErrorMsg2
  85. };
  86.  
  87.     
  88. #define kKeyStringsID 129 
  89. static enum {
  90.     kKeyNameStrID      =1,
  91.     kKeyIDStrID ,
  92.     kKeyTypeStrID,
  93.     kKeySizeStrID,
  94.     kKeyCreatedStrID,
  95.     kKeyExpiresStrID,
  96.     kKeyExpiredStrID,
  97.     kKeyRevokedStrID,
  98.     kKeyInvalidStrID,
  99.     kKeyValidStrID,
  100.     kKeyTrustedStrID,
  101.     kKeyUnTrustedStrID,
  102.     kKeyServerKeyIsEnabled,
  103.     kKeyServerKeyIsDisabled,
  104.     kKeyServerKeyIsRevoked,
  105.     kKeyServerKeyIsExpired
  106.      };
  107.  
  108.  
  109. static enum {
  110.     kHelpIconID            = 2200,
  111.     kHelpIconDisabledID    = 2201
  112. };
  113.  
  114. static enum{
  115.     kServerAuthPaneID = 1,
  116.     kSetupPaneID,
  117.     kAboutBoxPaneID
  118.  
  119. };
  120.  
  121. // ---------------------------------------------------------------------------
  122. #pragma mark Local Globals?
  123. // ---------------------------------------------------------------------------
  124.  
  125. static    TASIPPGPkey        gServerKey;
  126.  
  127. static     DialogPtr         gDialog = nil;
  128. static  TPane*            gPane    = nil;
  129. static  TPGPUAMPrefs*    gPrefs  = nil;
  130.  
  131. static  EventCallbackPtr gEventCallbackUPP = nil;
  132.  
  133. static  Boolean            gDialogForeground    = true;
  134. static     Boolean            appleGuideAvailable = false;
  135.  
  136. // ---------------------------------------------------------------------------
  137. #pragma mark Local Prototypes
  138. // ---------------------------------------------------------------------------
  139. static           short              GetDlgItemTop(DialogPtr dlog, int item);
  140. static           short              GetDlgItemBottom(DialogPtr dlog, int item);
  141. static pascal void            KeyIconDrawProc    (ControlHandle theControl, SInt16 thePart);
  142. static pascal ControlPartCode KeyIconHitTestProc (ControlHandle theControl, Point where);
  143. static pascal Boolean           LoginDialogFilterProc (DialogRef dialog, EventRecord *event, short *itemHit);
  144. static           DialogPtr       NewLoginDialog(StringPtr userName, StringPtr serverName, TPGPUAMPrefs* userPrefs);
  145. static           void               SetDialogDisclosureState (DialogPtr theDialog, Boolean expanded);
  146. static           void               LoginDialogIdle();
  147. static           void               UpdateLoginDialog(DialogPtr theDialog);
  148.  
  149. #pragma mark -
  150.  
  151.   
  152. // ---------------------------------------------------------------------------
  153. OSErr DoLoginDialog( StringPtr userName,
  154.                      StringPtr serverName, 
  155.                      short       *sessionRefNum,
  156.                      TPGPUAMPrefs*    userPrefs,
  157.                       LoginStartConnectionProcPtr startProc, 
  158.                       CancelConnectionProcPtr     cancelProc,
  159.                       UniversalProcPtr            eventProcUPP,
  160.                       void *context ) 
  161. // ---------------------------------------------------------------------------
  162.     {
  163.      ModalFilterUPP                 loginDialogFilterProcUPP = NewModalFilterProc (LoginDialogFilterProc);
  164.  
  165.     ControlHandle    theControl;    
  166.     short            itemNo;
  167.     Size            theSize;
  168.     long             response = 0;
  169.     GrafPtr            savePort;
  170.       OSErr            ErrNo         = noErr;
  171.     Boolean            busy;
  172.  
  173.      if(startProc == nil) return paramErr;
  174.      GetPort(&savePort);
  175.     
  176.     gEventCallbackUPP = eventProcUPP;
  177.     gPrefs = userPrefs;
  178.     
  179.     try
  180.         {
  181.      // setup prefs timelimit
  182.         EnablePassphraseCaching( userPrefs->GetCachePassPhrase() );
  183.          if( userPrefs->GetCachePassPhrase() )
  184.              SetPassphraseCacheTimeLimit( userPrefs->GetCachePassPhraseTimeLimit() );
  185.  
  186.       // Is apple Guide available ?
  187.         ErrNo = Gestalt(gestaltHelpMgrAttr, &response);
  188.         appleGuideAvailable =  (ErrNo == noErr && (response & (1 << gestaltAppleGuidePresent)));
  189.  
  190.       // update Key info
  191.          gServerKey.Initialize(gAFPSrvrSig);
  192.  
  193.     // create Login Dialog
  194.         ThrowIfNil( gDialog = NewLoginDialog(userName, serverName, userPrefs)); 
  195.  
  196.     // setup panel
  197.         gPane = new TASIPKeyPane(gDialog, CountDITL(gDialog),  &gServerKey);
  198.          gPane->Refresh();
  199.          
  200.          SetDialogDisclosureState(gDialog, userPrefs->GetDisclosureState()  );
  201.  
  202.     // Showtime!        
  203.         ShowWindow(gDialog);
  204.  
  205.         busy = true;
  206.          while(busy)
  207.         {
  208.                  ModalDialog(loginDialogFilterProcUPP, &itemNo);
  209.                 
  210.             switch(itemNo){
  211.             
  212.             case kCancelID:
  213.                      if( cancelProc) cancelProc(context);    
  214.                     busy = false;
  215.                     ErrNo = userCanceledErr;
  216.                      break;
  217.                     
  218.             case  kConnectID:
  219.                     GetDialogItemAsControl( gDialog, kConnectID, &theControl );
  220.                     DeactivateControl(theControl);
  221.     // force this to no longer be the default item
  222.     // else Appearance will re-activate it on process switch in.?
  223.                     SetDialogDefaultItem(gDialog,0);
  224.  
  225.                      GetDialogItemAsControl( gDialog, kProgressArrowsID, &theControl );
  226.                     ShowControl(theControl);
  227.                       GetDialogItemAsControl( gDialog, kUserNameID, &theControl );
  228.                     DeactivateControl(theControl);
  229.                      GetControlData( theControl, 0, kControlEditTextTextTag, (Size) 63, (Ptr)&userName[1], &theSize );
  230.                      userName[0] = (theSize &0xFF);
  231.                     ErrNo = (startProc)( userName,serverName,sessionRefNum,userPrefs, &gServerKey, LoginDialogIdle, context );
  232.                     busy = false;
  233.                     break;
  234.                     
  235.     // toggle disclosure triangle
  236.              case kKeyIcon:
  237.                          GetDialogItemAsControl( gDialog, kDisclosureTri, &theControl );
  238.                            SetControlValue(theControl,  0x1 ^ GetControlValue(theControl));
  239.            
  240.     // user toggled it
  241.             case kDisclosureTri:
  242.                           GetDialogItemAsControl( gDialog, kKeyIcon, &theControl );
  243.                           InvalRect(&(**theControl).contrlRect);
  244.  
  245.                          GetDialogItemAsControl( gDialog, kDisclosureTri, &theControl );
  246.                         SizeWindow(gDialog, 
  247.                                          (GetDialogWindow(gDialog)->portRect.right - 
  248.                                           GetDialogWindow(gDialog)->portRect.left),
  249.                                     ((GetControlValue(theControl) == 0)
  250.                                         ?GetDlgItemTop(gDialog, kSeperatorLine ) - 2 
  251.                                         :GetDlgItemBottom(gDialog, kTabsID)) - 4,true);
  252.                                         
  253.                         userPrefs->SetDisclosureState ( (GetControlValue(theControl) == 1 ));
  254.                          break;    
  255.                         
  256.             case kHelpItem:
  257.                         break;
  258.                                 
  259.             case kChangeKeyID:
  260.                         break;
  261.                              
  262.             case kIcon:
  263.                         break;
  264.                         
  265.             case kLaunchPGPKeysButton:
  266.                         LaunchApplication(kPGPkeysCreator);
  267.                         break;
  268.                         
  269.             case kTabsID:
  270.                           GetDialogItemAsControl( gDialog, kTabsID, &theControl );
  271.                           if(gPane) delete gPane; gPane = nil;
  272.                         switch (GetControlValue( theControl ) )
  273.                         {
  274.                             case kServerAuthPaneID:
  275.                                 gPane = new TASIPKeyPane(gDialog, CountDITL(gDialog), &gServerKey);
  276.                                 break;
  277.                                 
  278.                             case kSetupPaneID:
  279.                                 gPane = new TSetupPane(gDialog, CountDITL(gDialog),userPrefs );
  280.                                   break;
  281.                               
  282.                               case kAboutBoxPaneID:
  283.                                  gPane = new TAboutBoxPane(gDialog, CountDITL(gDialog) );
  284.                                    break;
  285.                         }
  286.                         if(gPane) gPane->Refresh();
  287.                          break;
  288.                                             
  289.             default:
  290.                     if((itemNo >= KLastLoginDialogItem) && gPane != nil)
  291.                     {
  292.                         gPane->ItemHit(itemNo);
  293.                         UpdateLoginDialog(gDialog);
  294.                     };
  295.                     
  296.                     break;
  297.             };
  298.         }
  299.     
  300.  
  301.     }
  302.  
  303. // Error Reporting
  304.     catch (...)
  305.     {
  306.         if(gDialog)
  307.         {
  308.              ClearKeyboardFocus(gDialog);
  309.              if(gPane) delete gPane;
  310.              DisposeDialog(gDialog);
  311.         }
  312.         SetPort(savePort);
  313.         throw;
  314.      }
  315.  
  316.     
  317.      ClearKeyboardFocus(gDialog);
  318.      if(gPane)  delete gPane;
  319.  
  320.      DisposeDialog(gDialog);
  321.     gDialog = nil;
  322.  
  323.     SetPort(savePort);    
  324.     
  325.       return ErrNo;
  326. }
  327.  
  328. // ---------------------------------------------------------------------------
  329. static DialogPtr NewLoginDialog(StringPtr userName, StringPtr serverName, TPGPUAMPrefs*    userPrefs )
  330. // ---------------------------------------------------------------------------
  331. {
  332.     ControlUserPaneDrawUPP         keyIconDrawProcUPP       = NewControlUserPaneDrawProc(KeyIconDrawProc);
  333.     ControlUserPaneHitTestUPP     keyIconHitTestProcUPP       = NewControlUserPaneHitTestProc(KeyIconHitTestProc);
  334.     
  335.     Handle                uamName;
  336.     DialogPtr            theDialog = nil;
  337.     ControlHandle        theControl;    
  338.     ControlFontStyleRec    fontInfo;
  339.     Str255                 text;
  340.      
  341.     // get Dialog Title
  342.      uamName = Get1Resource(kUAMStr,kUAMName);
  343.     if(!uamName) return nil;
  344.     
  345.     // Get the Dialog
  346.     theDialog = GetNewDialog(kLoginDialogID, nil, (WindowPtr)-1);
  347.     SetPort((GrafPtr) theDialog);
  348.   
  349.     // set dialog title
  350.     HLock(uamName);
  351.     SetWTitle(theDialog, (StringPtr) *uamName);
  352.     HUnlock(uamName);
  353.  
  354.      // setup Dialog Items
  355.     SetDialogCancelItem    (theDialog,kCancelID);    
  356.      SetDialogTracksCursor(theDialog,true);    
  357.      UpdateLoginDialog(theDialog);
  358.      
  359.      // setup key Icon & triangle text draw routine
  360.      GetDialogItemAsControl( theDialog, kKeyIcon, &theControl );
  361.     SetControlData(theControl, 0, kControlUserPaneDrawProcTag, sizeof(ControlUserPaneDrawUPP), (Ptr) &keyIconDrawProcUPP);
  362.     SetControlData(theControl, 0, kControlUserPaneHitTestProcTag, sizeof(ControlUserPaneHitTestUPP), (Ptr) &keyIconHitTestProcUPP);
  363.  
  364.      // load serverName info
  365.      ParamText( serverName, "\p","\p","\p");
  366.  
  367.      // Preload and setup User name field
  368.      GetDialogItemAsControl( theDialog, kUserNameID, &theControl );
  369.      SetControlData( theControl, 0, kControlEditTextTextTag, userName[0], (Ptr)(userName+1) );
  370.      SetKeyboardFocus(theDialog,theControl, kControlFocusNextPart);
  371.  
  372.     // Change key is not yet supported
  373.      GetDialogItemAsControl( theDialog, kChangeKeyID, &theControl );
  374.      DeactivateControl(theControl);
  375.  
  376.     // is appleguide around?
  377.      GetDialogItemAsControl( theDialog, kHelpItem, &theControl );
  378.     SetControlVisibility(theControl, appleGuideAvailable, true);
  379.  
  380.      fontInfo.font = kControlFontBigSystemFont;
  381.     fontInfo.just = teJustRight;
  382.     fontInfo.flags = kControlUseFontMask | kControlUseJustMask;
  383.  
  384.     // Name
  385.      GetDialogItemAsControl( theDialog, STXT4_Name, &theControl );
  386.     SetControlData( theControl, 0, kControlStaticTextStyleTag, sizeof fontInfo, (Ptr)&fontInfo);
  387.  
  388. // select proper font for disclosure text
  389.     fontInfo.just = teJustLeft;
  390.     fontInfo.font = kControlFontSmallSystemFont;
  391.  
  392.     GetDialogItemAsControl( theDialog, kDisclosureText, &theControl );
  393.      SetControlData( theControl, 0, kControlStaticTextStyleTag, sizeof fontInfo, (Ptr)&fontInfo);
  394.  
  395.       return theDialog;
  396. }
  397.  
  398.  
  399. // ---------------------------------------------------------------------------
  400. static pascal Boolean LoginDialogFilterProc
  401.     (DialogRef dialog, EventRecord *event, short *itemHit)
  402. // ---------------------------------------------------------------------------
  403. {
  404.     ModalFilterUPP  upp;
  405.     ControlHandle    theControl;    
  406.     Boolean handled;
  407.     
  408. // pre filtering
  409.     switch(event->what)
  410.         {
  411.         case nullEvent:
  412.             IdleControls(dialog);
  413.             if(gPane) gPane->Idle();
  414.             break;
  415.         
  416.         case mouseDown:
  417.             if(( dialog == gDialog) && (gPane != nil))
  418.                 if( gPane->HandleMouseDown(event)) return true;
  419.              break;
  420.             
  421. // handle switch into background?
  422.         case osEvt:
  423.                 if ((event->message >> 24) & suspendResumeMessage )     
  424.                 {    if( gDialogForeground = (event->message  & resumeFlag))
  425.                     {     
  426.                          // finder resume event
  427.                         // re-open PGP key database
  428.                         TPGPkey::OpenKeyDefaultRing();
  429.                         gServerKey.Initialize(gAFPSrvrSig);
  430.                         
  431.                          UpdateLoginDialog(gDialog);
  432.                          
  433.                          // update aprop panes    
  434.                         if(gPane) gPane->Refresh();
  435.                      } 
  436.                     else
  437.                     {
  438.                         // finder suspend event
  439.                         // close PGP key Database
  440.                          TPGPkey::CloseKeyRing();
  441.                      }    
  442.                 }
  443.             break;
  444.         }
  445.   
  446.   
  447.  
  448.     if (!GetStdFilterProc (&upp))
  449.         handled =  CallModalFilterProc (upp,dialog,event,itemHit);
  450.  
  451.     if(!handled)
  452.         CallUniversalProc( gEventCallbackUPP, kEventCallbackProcInfo, event);
  453.  
  454.     return handled;
  455. }
  456.  
  457. // ---------------------------------------------------------------------------
  458. static void LoginDialogIdle()
  459. // ---------------------------------------------------------------------------
  460. {
  461.     EventRecord event;
  462.     
  463.     event.what = nullEvent;
  464.     
  465.     LoginDialogFilterProc (gDialog, &event, 0);
  466. }
  467.  
  468.  
  469. // ---------------------------------------------------------------------------
  470. static void UpdateLoginDialog(DialogPtr dialog)
  471. // ---------------------------------------------------------------------------
  472. {
  473.     ControlHandle        theControl;    
  474.  
  475.     // can we connect with this key?
  476.     GetDialogItemAsControl( dialog, kConnectID, &theControl );
  477.  
  478.      if( gPrefs->GetAuthenticateServer() 
  479.          && (!gServerKey.CanVerify() || gServerKey.IsExpired() || gServerKey.IsRevoked() || gServerKey.IsDisabled())  )
  480.       {
  481.           SetDialogDefaultItem(dialog, 0);            
  482.          DeactivateControl(theControl);
  483.      }
  484.     else
  485.     {
  486.         ActivateControl(theControl);
  487.         SetDialogDefaultItem(dialog,kConnectID);            
  488.     }
  489.  
  490. }
  491.  
  492.  
  493. #pragma mark -
  494.  
  495. // ---------------------------------------------------------------------------
  496. static void SetDialogDisclosureState(DialogPtr theDialog, Boolean expanded)
  497. // ---------------------------------------------------------------------------
  498.  // activate the disclosure triangle with the proper  window default state
  499. {
  500.     ControlHandle        theControl;    
  501.  
  502.     GetDialogItemAsControl( theDialog, kDisclosureTri, &theControl );
  503.     SetControlValue(theControl, expanded?1:0);
  504.     SizeWindow(theDialog, 
  505.                      (GetDialogWindow(theDialog)->portRect.right - 
  506.                       GetDialogWindow(theDialog)->portRect.left),
  507.                 ((GetControlValue(theControl) == 0)
  508.                     ?GetDlgItemTop(theDialog, kSeperatorLine ) - 2 
  509.                     :GetDlgItemBottom(theDialog, kTabsID)) - 4,true);
  510.  
  511. }
  512.  
  513.  
  514. // ---------------------------------------------------------------------------
  515. static pascal void  KeyIconDrawProc(ControlHandle theControl, SInt16 thePart)
  516. // ---------------------------------------------------------------------------
  517. {
  518.     #pragma unused( thePart )
  519.     Rect            bounds;
  520.     Str255            text;
  521.      GrafPtr            savePort;
  522.  
  523.      GetPort(&savePort);
  524.       SetPort((GrafPtr) gDialog);
  525.  
  526.      bounds = (**theControl).contrlRect;
  527.  
  528.      
  529. // paint the proper Icon
  530.     bounds.right = bounds.left+16;
  531.     EraseRect(&bounds);    
  532.     PlotIconID(&bounds, atNone, gDialogForeground? ttNone: ttSelectedDisabled ,  gServerKey.GetIconID());
  533.     
  534. // get the right text string to display for the disclosure text
  535.     GetDialogItemAsControl( gDialog, kDisclosureTri, &theControl );
  536.     if( gServerKey.IsInitialized() )
  537.         GetIndString(text, kDialogStringsID,
  538.              ( GetControlValue(theControl) == 0) ?kShowDetailsStrID:kHideDetailsStrID);
  539.      else
  540.         GetIndString(text, kDialogStringsID,kServerKeyNotFound);
  541.  
  542.  
  543. // update the text line using an imbebded text item
  544.     GetDialogItemAsControl( gDialog, kDisclosureText, &theControl );
  545.     SetControlData( theControl, 0, kControlStaticTextTextTag, text[0], (Ptr)(text+1) );
  546.   
  547.   SetPort(savePort);
  548.  }
  549.  
  550.  
  551. // ---------------------------------------------------------------------------
  552.  static pascal ControlPartCode KeyIconHitTestProc(ControlHandle theControl, Point where)
  553. // ---------------------------------------------------------------------------
  554. {
  555.     #pragma unused( where )
  556.  
  557.     return kControlButtonPart;
  558. }
  559.  
  560.  
  561. #pragma mark -
  562.  
  563.     
  564.  // ---------------------------------------------------------------------------
  565. static short GetDlgItemTop(DialogPtr dlog, int item)
  566. // ---------------------------------------------------------------------------
  567.     {
  568.         short type; Handle hndl; Rect box;
  569.  
  570.         GetDialogItem(dlog,item,&type,&hndl,&box);
  571.         return (box.top);
  572.     }
  573.  
  574.  
  575.  // ---------------------------------------------------------------------------
  576. static short GetDlgItemBottom(DialogPtr dlog, int item)
  577. // ---------------------------------------------------------------------------
  578.     {
  579.         short type; Handle hndl; Rect box;
  580.  
  581.         GetDialogItem(dlog,item,&type,&hndl,&box);
  582.         return (box.bottom);
  583.     }
  584.  
  585.  
  586.  
  587.